package com.ypf.rpc.nettyHandler;


import com.ypf.rpc.factory.ServiceFactory;
import com.ypf.rpc.message.RpcRequestMessage;
import com.ypf.rpc.message.RpcResponseMessage;
import io.netty.channel.ChannelHandler;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.SimpleChannelInboundHandler;
import io.netty.util.ReferenceCountUtil;
import lombok.extern.slf4j.Slf4j;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

@Slf4j
@ChannelHandler.Sharable
public class RpcRequestMessageHandler extends SimpleChannelInboundHandler<RpcRequestMessage> {

    /**
     * 读事件
     * @param ctx
     * @param message
     * @throws Exception
     */
    @Override
    protected void channelRead0(ChannelHandlerContext ctx, RpcRequestMessage message) throws Exception {
        RpcResponseMessage rpcResponseMessage =new RpcResponseMessage();

        // 设置请求的序列号
        rpcResponseMessage.setSequenceId(message.getSequenceId());

        Object result;

        try {
            String interfaceName = message.getInterfaceName();
            Object service = ServiceFactory.serviceFactory.get(interfaceName);

            // 获取方法  方法名，所有参数
            Method method = service.getClass().getMethod(message.getMethodName(), message.getParameterTypes());

            // 调用方法 得到结果
            result = method.invoke(service, message.getParameterValue());

            // 设置返回值
            rpcResponseMessage.setReturnValue(result);
        } catch ( NoSuchMethodException | IllegalAccessException | InvocationTargetException e) {
            e.printStackTrace();
            rpcResponseMessage.setExceptionValue(new Exception("远程调用出错:"+e.getMessage()));
        }finally {
            ctx.writeAndFlush(rpcResponseMessage);
            ReferenceCountUtil.release(message);
        }

    }

}
